home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
eg0519s.zip
/
EG9413.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-01-04
|
67KB
|
2,458 lines
(*
* Copyright 1989, 1990 Eric Ng
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but
* without any warranty whatsoever, without even the implied warranties
* of merchantability or fitness for a particular purpose. See the
* accompanying GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to:
*
* Free Software Foundation, Inc.
* 675 Massachusetts Avenue
* Cambridge, Massachusetts 02139
*)
{$a-}
{$b-}
{$d-}
{$e-}
{$f-}
{$i-}
{$l-}
{$n-}
{$o-}
{$r-}
{$s-}
{$v-}
Program egaint;
Uses
Crt, Dos, Driver, Fonts, Graph;
Const
id : String [6] = 'egaint';
version : String [7] = '0.94.13';
copyright : String [27] = 'Copyright 1989-90 Eric Ng';
nshapes = 26; { different shapes }
shapesiz = 5; { max size of each shape }
xshapelevels = 4; { levels (classic, easy, medium, hard) }
xshapeclassic = 7; { different classic shapes }
xshapeeasy = 13; { different easy extended shapes }
xshapemedium = 19;
xshapehard = 26; { different hard extended shapes }
nkeybindings = 8; { different keyboard bindings }
nkeys = 5; { number of keys }
keydrop = 1; { index for the keys }
keyleft = 2;
keyright = 3;
keyrotateleft = 4;
keyrotateright = 5;
norients = 3; { different orientations }
ncolors = 14; { different colors }
nstyles = 3; { different styles }
nstyletabs = 7; { different style tables }
palettesiz = 16; { EGA palette size }
palettemap : array [0..palettesiz-1] of byte =
( 0, 7, 63, 47, 49, 25, 27, 10,
50, 44, 37, 39, 36, 38, 55, 62);
ngames = 256; { number of tournament games }
rowmin = 0; { playing field coordinates in pixels }
rowmax = 337;
colmin = 250;
colmax = 392;
pixelsperblock = 14; { pixels per block }
blockcols = 10; { columns in blocks }
maxdepth = 24; { max rows in blocks }
mindepth = 5; { min rows in blocks }
initrow = 0; { initial row and column for mkshape }
initcol = 5;
left = -1; { displacements for movement/rotation }
right = 1;
maxheight = maxdepth-mindepth; { maximum initial height }
maxlevel = 11; { maximum level }
filladd = 3; { constants for fill }
fillbase = 3;
dropdelay = 20; { constants for title drop }
dropinc = 5;
clearlimit = 5;
bonusempty = 500; { bonus for an empty pit }
bonusrowclear = 3; { bonus for clearing a row }
bonusmultclear = 2; { bonus for clearing multiple rows }
bonusnext = 1; { bonus for not using show next shape }
bonusguide = 2; { bonus fot not using show guide }
bonusshadow = 1; { bonus for not using show shadow }
bonushidden = 3; { bonus for using hidden blocks }
info = 0; { information element in shape table }
cleartone = 220; { row clear tone }
cleartonedelay = 10; { row clear tone delay }
nhiscores = 15; { number of high scores }
hiscorename = 'egaint.rec'; { high score file name }
configname = 'egaint.rc'; { configuration file name }
Type
displaytype = (bw, color, mono, plasma);
mesgcolors = (normal, high);
bufstr = String [32];
rinfotype = Array [1..clearlimit] Of byte;
hiscorerec = Record
score : longint;
level : byte;
rowsclear : word;
date : String [8];
time : String [8];
name : bufstr;
version : String [7]
End;
Const
shapetab : Array [1..nshapes, 0..shapesiz-1, 1..2] Of shortint =
{ bar } (((3, 2), ( 0, -1), ( 0, 1), ( 0, 2), ( 0, 0)),
{ tee } ((3, 2), ( 0, -1), ( 1, 0), ( 0, 1), ( 0, 0)),
{ box } ((3, 3), ( 1, 0), ( 0, 1), ( 1, 1), ( 0, 0)),
{ zig } ((3, 3), ( 0, -1), ( 1, 0), ( 1, 1), ( 0, 0)),
{ zag } ((3, 3), ( 1, -1), ( 1, 0), ( 0, 1), ( 0, 0)),
{ ell } ((3, 3), ( 1, -1), ( 0, -1), ( 0, 1), ( 0, 0)),
{ lel } ((3, 3), ( 0, -1), ( 0, 1), ( 1, 1), ( 0, 0)),
{ easy } ((0, 0), ( 0, 0), ( 0, 0), ( 0, 0), ( 0, 0)),
((1, 0), ( 0, 1), ( 0, 0), ( 0, 0), ( 0, 0)),
((1, 1), ( 1, 1), ( 0, 0), ( 0, 0), ( 0, 0)),
((2, 1), ( 1, 0), ( 0, 1), ( 0, 0), ( 0, 0)),
((2, 1), ( 0, -1), ( 0, 1), ( 0, 0), ( 0, 0)),
{ 13 } ((4, 3), ( 0, -2), ( 0, -1), ( 0, 1), ( 0, 2)),
{ medium } ((2, 3), ( 1, -1), ( 1, 1), ( 0, 0), ( 0, 0)),
((2, 4), ( 1, -1), ( 0, 1), ( 0, 0), ( 0, 0)),
((2, 4), ( 0, -1), ( 1, 1), ( 0, 0), ( 0, 0)),
((4, 4), ( 1, -1), ( 0, -1), ( 0, 1), ( 1, 1)),
((4, 4), (-1, -1), (-1, 0), ( 1, 0), (-1, 1)),
{ 19 } ((4, 5), ( 0, -1), (-1, 0), ( 1, 0), ( 0, 1)),
{ hard } ((4, 5), ( 1, -1), ( 0, -1), (-1, 0), (-1, 1)),
((4, 6), ( 1, -1), ( 0, -1), ( 0, 1), (-1, 1)),
((4, 6), (-1, -1), ( 0, -1), ( 0, 1), ( 1, 1)),
((4, 6), ( 2, 0), ( 1, 0), ( 0, 1), ( 0, 2)),
((3, 7), (-1, -1), ( 1, 0), (-1, 1), ( 0, 0)),
((3, 7), ( 1, -1), ( 2, 0), ( 1, 1), ( 0, 0)),
{ 26 } ((4, 7), (-1, -1), ( 1, -1), (-1, 1), ( 1, 1)));
shapecolortab : Array [displaytype, 1..ncolors] Of byte =
{ bw } ((7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15),
{ color } (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
{ mono } (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
{ plasma } (1, 4, 7, 1, 4, 7, 1, 4, 7, 1, 4, 7, 1, 4));
{ (1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7)); }
mesgcolortab : Array [displaytype, mesgcolors] Of byte =
{ bw } ((7, 15),
{ color } (1, 2),
{ mono } (1, 1),
{ plasma } (4, 7));
filltab : Array [1..nstyles] Of FillPatternType =
(($aa, $55, $aa, $55, $aa, $55, $aa, $55),
($99, $cc, $66, $33, $99, $cc, $66, $33),
($99, $33, $66, $cc, $99, $33, $66, $cc));
timedelaytab : Array [1..maxlevel] Of byte =
(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
advancetab : Array [1..maxlevel] Of word =
(10, 20, 30, 40, 50, 60, 70, 80, 90, 200, 65535);
xshapetitles : Array [1..xshapelevels] Of String [7] =
('Classic',
'Easy',
'Medium',
'Hard');
styleblocktitles: Array [1..nstyletabs] Of String[20] =
('New',
'Classic',
'Pumped Full of Drugs',
'Barbed Wire Kisses',
'Arpeggiator',
'Elephant Stone',
'Really P.F.D.');
keynames : array [1..nkeybindings, 1..nkeys] of string[2] =
(('Sp', 'J', 'L', 'I', 'K'),
('Sp', 'J', 'L', 'K', 'I'),
('Sp', 'H', 'L', 'J', 'K'),
('Sp', 'S', 'F', 'E', 'D'),
('Sp', 'S', 'F', 'D', 'E'),
('Sp', 'A', 'F', 'S', 'D'),
('0', '4', '6', '8', '5'),
('Sp', 'J', 'L', 'I', 'K'));
keybindingtab : array [1..nkeybindings, 1..nkeys] of byte =
{ classic } ((57, 36, 38, 23, 37), { sp, j, l, i, k }
{ russian } (57, 36, 38, 37, 23), { sp, j, l, k, i }
{ berkeley } (57, 35, 38, 36, 37), { sp, h, l, j, k }
{ left-handed } (57, 31, 33, 18, 32), { sp, s, f, e, d }
{ finnish } (57, 31, 33, 32, 18), { sp, s, f, d, e }
{ sf } (57, 30, 33, 31, 32), { sp, a, f, s, d }
{ arrow } (82, 75, 77, 72, 76), { ins, lf, rt, up, 5 }
{ user-defined } (00, 00, 00, 00, 00));
keybindingtitles: array [1..nkeybindings] of string[13] =
('Classic',
'Russian',
'Berkeley',
'Left-handed',
'Finnish',
'San Francisco',
'Arrow',
'User-defined');
Var
shapecolors : Array [1..ncolors] Of byte;
field : Array [0..maxdepth+1, 1..blockcols] Of boolean;
{ fieldshadows : Array [1..blockcols] Of boolean; }
hiscore : Array [1..nhiscores] Of hiscorerec;
styletab : Array [1..ncolors, 1..nstyles] Of pointer;
xstyletabs : Array [1..nstyletabs, 1..ncolors, 1..nstyles] Of pointer;
xshapetab : Array [1..nshapes, 0..norients, 1..shapesiz-1, 1..2] Of
shortint;
yshapetab : Array [1..nshapes, 0..norients, 1..shapesiz-1, 1..2] Of
shortint;
keybinding : array [1..nkeys] of byte;
buf, buf2, buf3 : String[255];
colorhigh : byte;
colornormal : byte;
curtain : Array [boolean] Of pointer;
emptyrow : pointer;
fconfig : Text;
fhiscore : File of hiscorerec;
filler : pointer;
graphdriver : integer;
graphmode : integer;
savemode : word;
savenumlock : byte;
scrollptr : pointer;
{ shadows : pointer; }
bonus : byte;
rowsclear : word;
score : longint;
shapemap : byte;
userpalette : palettetype;
level : byte;
Const
endrun : boolean = False;
page : integer = 0;
display : displaytype = color;
height : byte = 0;
initlevel : byte = 5;
depth : byte = maxdepth;
shownext : boolean = True;
showguide : boolean = false;
showshadow : boolean = False;
styleblocks : byte = 0;
title : boolean = True;
tones : boolean = True;
tournament : boolean = False;
tournamentgame : byte = 0;
xshape : byte = 1;
binding : byte = 1;
Function gettimer : longint;
Inline($28/$e4/ { sub ah,ah }
$cd/$1a/ { int 1ah }
$89/$d0/ { mov ax,dx }
$89/$ca); { mov dx,cx }
procedure numlock(flag : boolean);
begin
if flag then
begin
savenumlock := mem[$0000:$0417];
mem[$0000:$0417] := mem[$0000:$0417] or $20
end
else
if savenumlock and $20 = 0 then
mem[$0000:$0417] := mem[$0000:$0417] and $df
end;
(*
if flag then
inline($1e/ { push ds ; save caller's ds }
$31/$c0/ { xor ax,ax ; zero ax }
$8e/$d8/ { mov ds,ax ; load ds }
$a0/$17/$04/ { mov al,[0417] ; get keyboard flags }
$0c/$20/ { or al,20 ; turn on num lock }
$a2/$17/$04/ { mov [0417],al ; save keyboard flags }
$1f) { pop ds ; restore caller's ds }
else
inline($1e/ { push ds ; save caller's ds }
$31/$c0/ { xor ax,ax ; zero ax }
$8e/$d8/ { mov ds,ax ; load ds }
$a0/$17/$04/ { mov al,[0417] ; get keyboard flags }
$24/$df/ { and al,df ; turn off num lock }
$a2/$17/$04/ { mov [0417],al ; save keyboard flags }
$1f) { pop ds ; restore caller's ds }
end; *)
function getkey : word;
inline($30/$e4/ { xor ah,ah }
$cd/$16); { int 16 }
Procedure dographics;
Begin
savemode := LastMode;
DetectGraph(GraphDriver, GraphMode);
Case GraphDriver Of
EGAMono: Begin
initgraph(graphdriver, graphmode, '');
setgraphmode(egamonohi);
display := mono;
end;
EGA: Begin
InitGraph(GraphDriver, GraphMode, '');
SetGraphMode(EGAHi)
End;
HercMono: Begin
initgraph(graphdriver, graphmode, '');
setgraphmode(HercMonoHi);
display := mono;
End;
VGA: Begin
InitGraph(GraphDriver, GraphMode, '');
SetGraphMode(VGAMed)
End;
Else
Begin
WriteLn(id,
' requires either an EGA with 256k RAM, VGA, or Hercules graphics adapter.');
Halt(0)
End
End;
setactivepage(0);
cleardevice;
setactivepage(1);
cleardevice;
End;
Procedure dotext;
Begin
CloseGraph;
TextMode(savemode)
End;
Procedure fillzero(Var s : bufstr);
Var
i : integer;
Begin
For i := 1 To Length(s) Do
If s[i] = #32 Then
s[i] := '0'
End;
Procedure placewindow(x1, y1, x2, y2 : integer);
Begin
Rectangle(x1, y1, x2, y2);
Bar(x2+1, y1+8, x2+3, y2);
Bar(x1+8, y2+1, x2+3, y2+2)
End;
Procedure putshape(x, y : integer;
s : byte;
p : pointer);
Var
i : integer;
xs : byte;
Begin
xs := shapetab[s, info, 1];
PutImage(x, y, p^, XORPut);
For i := 1 To xs Do
PutImage(x+xshapetab[s, 0, i, 2], y+xshapetab[s, 0, i, 1], p^, XORPut)
End;
Procedure init;
Var
i, j, isiz : integer;
x, y : integer;
Procedure abortgraphics;
Begin
WriteLn(GraphErrorMsg(GraphResult));
Halt(0)
End; {-abortgraphics-}
Begin {-init-}
numlock(true);
Randomize;
userpalette.colors[0] := -1;
Assign(fconfig, configname);
FileMode := 0; { read-only }
Reset(fconfig);
If IOResult = 0 Then
Begin
While Not Eof(fconfig) Do
Begin
ReadLn(fconfig, buf3);
If buf3[1] <> '#' Then
Begin
i := Pos('=', buf3);
buf2 := Copy(buf3, 1, i-1);
buf := Copy(buf3, i+1, Length(buf3)-i);
{ WriteLn(buf2);
WriteLn(buf);
ReadLn; }
If buf2 = 'display' Then
Case buf[1] Of
'B', 'b': display := bw;
'C', 'c': display := color;
'M', 'm': display := mono;
'P', 'p': display := plasma
End;
if buf2 = 'depth' then
begin
val (buf, i, j);
if (j = 0) and (i in [mindepth..maxdepth]) then
depth := i;
end;
If buf2 = 'height' Then
Begin
Val(buf, i, j);
If (j = 0) And (i In [0..2*maxheight]) Then
height := i
End;
If buf2 = 'level' Then
Begin
Val(buf, i, j);
If (j = 0) And (i In [1..maxlevel]) Then
initlevel := i
End;
If buf2 = 'shownext' Then
Case buf[1] Of
'Y', 'y': shownext := True;
'N', 'n': shownext := False
End;
If buf2 = 'showguide' Then
Case buf[1] Of
'Y', 'y': showguide := True;
'N', 'n': showguide := False
End;
{ If buf2 = 'showshadow' Then
Case buf[1] Of
'Y', 'y': showshadow := False;
'N', 'n': showshadow := False
End; }
If buf2 = 'tournament' Then
Case buf[1] Of
'Y', 'y': tournament := True;
'N', 'n': tournament := False
End;
If buf2 = 'tournamentgame' Then
Begin
Val(buf, i, j);
If (j = 0) And (i In [0..ngames-1]) Then
tournamentgame := i
End;
If buf2 = 'xshape' Then
Case buf[1] Of
'C', 'c': xshape := 1;
'E', 'e': xshape := 2;
'M', 'm': xshape := 3;
'H', 'h': xshape := 4
End;
If buf2 = 'styleblocks' Then
Case buf[1] Of
'N', 'n': styleblocks := 1;
'C', 'c': styleblocks := 2;
'P', 'p': styleblocks := 3;
'B', 'b': styleblocks := 4;
'A', 'a': styleblocks := 5;
'E', 'e': styleblocks := 6;
'R', 'r': styleblocks := nstyletabs
End;
If buf2 = 'sound' Then
Case buf[1] Of
'Y', 'y': tones := True;
'N', 'n': tones := False
End;
If buf2 = 'title' Then
Case buf[1] Of
'Y', 'y': title := True;
'N', 'n': title := False
End;
if buf2 = 'palette' then
begin
for x := 0 to palettesiz-2 do
begin
i := pos (',', buf);
if i <> 0 then
begin
buf3 := copy (buf, 1, i-1);
buf := copy (buf, i+1, length (buf)-i);
val(buf3, y, j);
if (j = 0) and (y in [0..63]) then
userpalette.colors[x] := y
else
userpalette.colors[0] := -1;
end
else
userpalette.colors[0] := -1;
end;
val(buf,y,j);
if (j = 0) and (y in [0..63]) then
userpalette.colors[palettesiz-1] := y
else
userpalette.colors[0] := -1;
end;
if buf2 = 'keybinding' then
Case buf[1] Of
'C', 'c': binding := 1;
'R', 'r': binding := 2;
'B', 'b': binding := 3;
'L', 'l': binding := 4;
'F', 'f': binding := 5;
'S', 's': binding := 6;
'A', 'a': binding := 7;
'U', 'u': binding := 8;
'0'..'9': begin
binding := 8;
for x := 1 to nkeys-1 do
begin
i := pos (',', buf);
if i <> 0 then
begin
buf3 := copy(buf, 1, i-1);
buf := copy(buf, i+1, length(buf)-i);
val(buf3, y, j);
if (j = 0) and (y in [0..255]) then
keybindingtab[nkeybindings, x] := y
else
keybindingtab[nkeybindings, 1] := 0;
end
else
keybindingtab[nkeybindings, 1] := 0;
end;
val(buf, y, j);
if (j = 0) and (y in [0..255]) then
keybindingtab[nkeybindings, nkeys] := y
else
keybindingtab[nkeybindings, 1] := 0;
end
end
End
End;
Close(fconfig)
End;
If ParamCount > 0 Then
Begin
buf := Copy(ParamStr(1), 1, 1);
Case buf[1] Of
'B', 'b': display := bw;
'C', 'c': display := color;
'M', 'm': display := mono;
'P', 'p': display := plasma
End
End;
If RegisterBGIdriver(@EGAVGADriver) < 0 Then
abortgraphics;
if registerbgidriver(@hercdriver) < 0 then
abortgraphics;
If RegisterBGIfont(@SansSerifFontProc) < 0 Then
abortgraphics;
If RegisterBGIfont(@SmallFontProc) < 0 Then
abortgraphics;
dographics;
For i := 1 To nshapes Do
For j := 1 To shapesiz-1 Do
Begin
xshapetab[i, 0, j, 1] := pixelsperblock*shapetab[i, j, 1];
yshapetab[i, 0, j, 1] := shapetab[i, j, 1];
xshapetab[i, 0, j, 2] := pixelsperblock*shapetab[i, j, 2];
yshapetab[i, 0, j, 2] := shapetab[i, j, 2];
xshapetab[i, 1, j, 1] := pixelsperblock*shapetab[i, j, 2];
yshapetab[i, 1, j, 1] := shapetab[i, j, 2];
xshapetab[i, 1, j, 2] := -pixelsperblock*shapetab[i, j, 1];
yshapetab[i, 1, j, 2] := -shapetab[i, j, 1];
xshapetab[i, 2, j, 1] := -pixelsperblock*shapetab[i, j, 1];
yshapetab[i, 2, j, 1] := -shapetab[i, j, 1];
xshapetab[i, 2, j, 2] := -pixelsperblock*shapetab[i, j, 2];
yshapetab[i, 2, j, 2] := -shapetab[i, j, 2];
xshapetab[i, 3, j, 1] := -pixelsperblock*shapetab[i, j, 2];
yshapetab[i, 3, j, 1] := -shapetab[i, j, 2];
xshapetab[i, 3, j, 2] := pixelsperblock*shapetab[i, j, 1];
yshapetab[i, 3, j, 2] := shapetab[i, j, 1]
End;
For i := 1 To ncolors Do
shapecolors[i] := shapecolortab[display, i];
colornormal := mesgcolortab[display, normal];
colorhigh := mesgcolortab[display, high];
FillChar(hiscore, SizeOf(hiscore), 0);
i := 1;
Assign(fhiscore, hiscorename);
FileMode := 0; { read-only }
Reset(fhiscore);
If IOResult = 0 Then
Begin
While (i <= nhiscores) And (Not Eof(fhiscore)) Do
Begin
Read(fhiscore, hiscore[i]);
Inc(i)
End;
Close(fhiscore)
End;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
GetMem(scrollptr, ImageSize(colmin+1, rowmin, colmax-1,
rowmax+pixelsperblock));
getmem(emptyrow, ImageSize(colmin+1, rowmin, colmax-1,
rowmin+pixelsperblock+1));
isiz := ImageSize(colmin+1, rowmin, colmax-1, rowmin+pixelsperblock);
{ isiz := ImageSize(0, 0, pixelsperblock, pixelsperblock);
SetColor(colorhigh);
SetFillPattern(filltab[1], colornormal);
Bar(0, 0, pixelsperblock, pixelsperblock Shr 1);
GetMem(shadows, isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock Shr 1, shadows^);
PutImage(0, 0, shadows^, XORPut); }
isiz := ImageSize(0, 0, pixelsperblock, pixelsperblock);
SetColor(colornormal);
SetFillStyle(SolidFill, colornormal);
Bar(1, 1, pixelsperblock-1, pixelsperblock-1);
SetColor(Black);
Rectangle(3, 3, pixelsperblock-3, pixelsperblock-3);
Line(1, 1, 3, 3);
Line(1, pixelsperblock-1, 3, pixelsperblock-3);
Line(pixelsperblock-1, 1, pixelsperblock-3, 3);
Line(pixelsperblock-1, pixelsperblock-1, pixelsperblock-3,
pixelsperblock-3);
For i := 1 To ncolors Do { new }
For j := 1 To nstyles Do
Begin
SetFillPattern(filltab[j], shapecolors[i]);
Bar(4, 4, pixelsperblock-4, pixelsperblock-4);
GetMem(xstyletabs[1, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[1, i, j]^)
End;
For i := 1 To ncolors Do { pumped full of drugs }
For j := 1 To nstyles Do
Begin
SetFillPattern(filltab[Random(nstyles)+1],
shapecolors[Random(ncolors)+1]);
Bar(4, 4, 7, 7);
SetFillPattern(filltab[Random(nstyles)+1],
shapecolors[Random(ncolors)+1]);
Bar(7, 4, 10, 7);
SetFillPattern(filltab[Random(nstyles)+1],
shapecolors[Random(ncolors)+1]);
Bar(4, 7, 7, 10);
SetFillPattern(filltab[Random(nstyles)+1],
shapecolors[Random(ncolors)+1]);
Bar(7, 7, 10, 10);
GetMem(xstyletabs[3, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[3, i, j]^)
End;
if display = mono then
begin
for i := 1 to ncolors do { barbed wire kisses }
for j := 1 to nstyles do
begin
for x := 4 to pixelsperblock-4 do
for y := 4 to pixelsperblock-4 do
begin
if random(3) > 0 then
putpixel(x, y, shapecolors[i])
else
putpixel(x, y, 0);
end; { for }
GetMem(xstyletabs[4, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[4, i, j]^)
End
end
else
begin
for i := 1 to ncolors do
for j := 1 to nstyles do
begin
for x := 4 to pixelsperblock-4 do
for y := 4 to pixelsperblock-4 do
begin
if random(2) = 0 then
putpixel(x, y, shapecolors[i])
else
putpixel(x, y, shapecolors[random(ncolors)+1])
end; { for }
GetMem(xstyletabs[4, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[4, i, j]^)
End
end;
SetFillPattern(filltab[1], colornormal);
Bar(4, 4, pixelsperblock-4, pixelsperblock-4);
GetMem(filler, isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, filler^);
PutImage(0, 0, filler^, XORPut);
For i := 1 To ncolors Do { classic }
Begin
SetColor(shapecolors[i]);
For j := 1 To nstyles Do
Begin
SetFillPattern(filltab[j], shapecolors[i]);
Rectangle(1, 1, pixelsperblock-1, pixelsperblock-1);
Bar(3, 3, pixelsperblock-3, pixelsperblock-3);
GetMem(xstyletabs[2, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[2, i, j]^)
End
End;
For i := 1 To ncolors Do { arpeggiator }
Begin
SetColor(shapecolors[i]);
For j := 1 To nstyles Do
Begin
SetFillPattern(filltab[j], shapecolors[i]);
bar(1, 1, pixelsperblock-1, pixelsperblock-1);
GetMem(xstyletabs[5, i, j], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[5, i, j]^)
End
End;
if display = mono then
begin
for i := 1 to ncolors do { elephant stone }
for j := 1 to nstyles do
begin
for x := 1 to pixelsperblock-1 do
for y := 1 to pixelsperblock-1 do
begin
if random(3) > 0 then
putpixel(x, y, shapecolors[i])
else
putpixel(x, y, 0);
end; { for }
getMem(xstyletabs[6, i, j], isiz);
getImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[6, i, j]^)
end
end
else
begin
for i := 1 to ncolors do { elephant stone }
for j := 1 to nstyles do
begin
for x := 1 to pixelsperblock-1 do
for y := 1 to pixelsperblock-1 do
begin
if random(2) = 0 then
putpixel(x, y, shapecolors[i])
else
putpixel(x, y, shapecolors[random(ncolors)+1])
end; { for }
getMem(xstyletabs[6, i, j], isiz);
getImage(0, 0, pixelsperblock, pixelsperblock, xstyletabs[6, i, j]^)
end;
end;
SetColor(colorhigh);
SetFillPattern(filltab[2], colornormal);
Bar(1, 1, pixelsperblock-1, pixelsperblock-1);
GetMem(curtain[true], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, curtain[true]^);
SetFillPattern(filltab[3], colornormal);
Bar(1, 1, pixelsperblock-1, pixelsperblock-1);
GetMem(curtain[false], isiz);
GetImage(0, 0, pixelsperblock, pixelsperblock, curtain[false]^);
PutImage(0, 0, curtain[false]^, XORPut);
For i := 1 To ncolors Do
For j := 1 To nstyles Do
xstyletabs[nstyletabs, i, j] := xstyletabs[Random(nstyletabs-1)+1, i, j];
{ Random(ncolors)+1,
Random(nstyles)+1] }
if display = color then
begin
userpalette.size := palettesiz;
if userpalette.colors[0] = -1 then
for i := 0 to palettesiz-1 do
userpalette.colors[i] := palettemap[i];
setallpalette(userpalette)
end
End; {-init-}
Procedure drawtitle;
Const
titlesiz = 95;
titletab : Array [1..titlesiz, 1..2] Of integer =
(( 75, 57), ( 75, 71), ( 75, 85), ( 75, 99),
( 75, 113), ( 75, 127), ( 75, 141),
( 89, 57), ( 89, 99), ( 89, 141),
(103, 57), (103, 99), (103, 141),
(117, 57), (117, 99), (117, 141),
(131, 57), (131, 141),
(159, 71), (159, 85), (159, 99), (159, 113),
(159, 127),
(173, 57), (173, 141),
(187, 57), (187, 141),
(201, 57), (201, 99), (201, 141),
(215, 71), (215, 99), (215, 113), (215, 127),
(243, 71), (243, 85), (243, 99), (243, 113),
(243, 127), (243, 141),
(257, 57), (257, 99),
(271, 57), (271, 99),
(285, 57), (285, 99),
(299, 71), (299, 85), (299, 99), (299, 113),
(299, 127), (299, 141),
(327, 57), (327, 141),
(341, 57), (341, 141),
(355, 57), (355, 71), (355, 85), (355, 99),
(355, 113), (355, 127), (355, 141),
(369, 57), (369, 141),
(383, 57), (383, 141),
(411, 57), (411, 71), (411, 85), (411, 99),
(411, 113), (411, 127), (411, 141),
(425, 71),
(439, 85),
(453, 99),
(467, 57), (467, 71), (467, 85), (467, 99),
(467, 113), (467, 127), (467, 141),
(495, 57),
(509, 57),
(523, 57), (523, 71), (523, 85), (523, 99),
(523, 113), (523, 127), (523, 141),
(537, 57),
(551, 57));
Var
test : Array [1..titlesiz] Of boolean;
ch : word;
i, j, c, s : integer;
x, y1, y2 : integer;
p : pointer;
Begin {-drawtitle-}
FillChar(test, SizeOf(test), 0);
If styleblocks = 0 Then
styleblocks := Random(nstyletabs-1)+1;
s := 1;
if title then
begin
For i := 1 To titlesiz Do
Begin
Repeat
j := Random(titlesiz)+1
Until Not test[j];
c := Random(ncolors)+1;
If styleblocks = 3 Then
s := Random(nstyles)+1;
x := titletab[j, 1];
If KeyPressed Then
y1 := titletab[j, 2]
Else
Begin
y1 := 0;
y2 := dropinc
End;
p := xstyletabs[styleblocks, c, s];
PutImage(x, y1, p^, XORPut);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
While (Not KeyPressed) And (y2 < titletab[j, 2]) Do
Begin
PutImage(x, y2, p^, XORPut);
Delay(dropdelay);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
PutImage(x, y1, p^, XORPut);
y1 := y2;
Inc(y2, dropinc)
End;
PutImage(x, titletab[j, 2], p^, XORPut);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
PutImage(x, y1, p^, XORPut);
PutImage(x, titletab[j, 2], p^, XORPut);
test[j] := True
End;
While KeyPressed Do
ch := getkey;
SetTextJustify(CenterText, TopText);
SetColor(colorhigh);
SetTextStyle(SansSerifFont, HorizDir, 4);
OutTextXY(320, 7, 'Welcome to version '+version+' of');
OutTextXY(320, 162, copyright);
SetTextStyle(SmallFont, HorizDir, 4);
OutTextXY(320, 215,
'This program comes with ABSOLUTELY NO WARRANTY; see the accompanying GNU '+
'General Public License for full');
OutTextXY(320, 227,
'details. You should have received a copy along with this program (see the '+
'file COPYING). If not, write to:');
OutTextXY(320, 239,
'Free Software Foundation, Inc., 675 Massachusetts Avenue, Cambridge, '+
'Massachusetts 02139');
OutTextXY(320, 323,
'Eric Ng, 1906 Milvia Street, Berkeley, California 94704');
OutTextXY(320, 335, 'Internet: erc@irss.njit.edu');
SetColor(colornormal);
OutTextXY(160, 257, 'To obtain the full source code and/or the');
OutTextXY(160, 269, 'latest version of this program, call');
OutTextXY(160, 305, 'or see the included file GETTING.');
OutTextXY(480, 257, 'Requirements: IBM PC, PS/2, or 100%');
OutTextXY(480, 269, 'compatible (8 MHz or faster CPU is strongly');
OutTextXY(480, 281, 'recommended); an EGA with 256k RAM, VGA,');
OutTextXY(480, 293, 'Hercules graphics adapter; and 256k free');
OutTextXY(480, 305, 'system RAM.');
SetColor(colorhigh);
OutTextXY(160, 281, 'The Odyssey +1 201 984 6574');
OutTextXY(160, 293, 'The PC GFX Exchange +1 415 337 5416');
{ OutTextXY(160, 293, 'The Bandersnatch +1 201 766-3801') }
end;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
ClearDevice;
if title then
begin
Repeat Until KeyPressed;
Repeat
ch := getkey
Until Not KeyPressed
end
End; {-drawtitle-}
procedure getkeybindings;
procedure drawkeybindings;
begin
SetTextJustify(CenterText, TopText);
SetColor(colorhigh);
SetTextStyle(SansSerifFont, HorizDir, 4);
OutTextXY(320, 2, id+' '+version);
SetColor(colornormal);
SetTextStyle(DefaultFont, HorizDir, 1);
OutTextXY(320, 40, 'Key Bindings');
SetFillStyle(SolidFill, colornormal);
placewindow(237, 60, 403, 132);
SetTextStyle(SmallFont, HorizDir, 4);
outtextxy(320, 86, 'Press the key for');
end;
procedure getgetkey(n : integer);
var
ch : word;
i : integer;
begin
repeat
repeat
ch := getkey
until lo(ch) in [32..126];
i := 1;
while (keybindingtab[nkeybindings, i] <> hi(ch)) and (i < n) do
inc(i);
if i = n then
begin
keybindingtab[nkeybindings, n] := hi(ch);
if tones then
begin
Sound(cleartone);
Delay(cleartonedelay);
NoSound
end
end
until i = n
end; {-getgetkey-}
begin {-getkeybindings-}
drawkeybindings;
setvisualpage(page);
setcolor(colorhigh); outtextxy(320, 98, 'Drop');
getgetkey(keydrop);
setcolor(black); outtextxy(320, 98, 'Drop');
setcolor(colorhigh); outtextxy(320, 98, 'Move Left');
getgetkey(keyleft);
setcolor(black); outtextxy(320, 98, 'Move Left');
setcolor(colorhigh); outtextxy(320, 98, 'Move Right');
getgetkey(keyright);
setcolor(black); outtextxy(320, 98, 'Move Right');
setcolor(colorhigh); outtextxy(320, 98, 'Rotate Left');
getgetkey(keyrotateleft);
setcolor(black); outtextxy(320, 98, 'Rotate Left');
setcolor(colorhigh); outtextxy(320, 98, 'Rotate Right');
getgetkey(keyrotateright);
setcolor(black); outtextxy(320, 98, 'Rotate Right')
end; {-getkeybindings-}
Procedure initgame;
Var
i, j : integer;
Procedure getoptions;
Const
noptions = 10;
optiontitles : Array [1..noptions] Of String [22] =
('Tournament Game',
'Tournament Game Number',
'Initial Level',
'Initial Height',
'Show Next',
'Extended Shapes',
'Block Style',
'Key Bindings',
'Pit Depth',
'Show Guide');
optiony = 80;
optionyinc = 22;
Var
done : boolean;
o : byte;
bigheight : byte;
ch : word;
Procedure drawoptions;
Var
i : integer;
Begin {-drawoptions-}
SetTextJustify(CenterText, TopText);
SetColor(colorhigh);
SetTextStyle(SansSerifFont, HorizDir, 4);
OutTextXY(320, 2, id+' '+version);
SetColor(colornormal);
SetTextStyle(DefaultFont, HorizDir, 1);
OutTextXY(320, 40, 'Options');
OutTextXY(320, 330,
'Press the arrow keys to move, Enter to rotate, and the Space Bar when done.');
SetFillStyle(SolidFill, colornormal);
placewindow(150, 65, 490, 307);
SetTextJustify(LeftText, TopText);
For i := 1 To noptions Do
OutTextXY(200, optiony+(optionyinc*(i-1))+3, optiontitles[i])
End; {-drawoptions-}
Procedure showflag(f : boolean;
y : integer);
Begin
If f Then
OutTextXY(440, optiony+(optionyinc*(y-1)), 'Yes')
Else
OutTextXY(440, optiony+(optionyinc*(y-1)), 'No')
End; {-showflag-}
Procedure showoption(o : byte);
Begin
Case o Of
1: showflag(tournament, o);
2: Begin
Str(tournamentgame, buf);
OutTextXY(440, optiony+(optionyinc*(o-1)), buf)
End;
3: Begin
Str(level, buf);
OutTextXY(440, optiony+(optionyinc*(o-1)), buf)
End;
4: Begin
If height > maxheight Then
begin
str(height-maxheight, buf);
buf := 'Hidden '+buf
end
Else
Str(height, buf);
OutTextXY(440, optiony+(optionyinc*(o-1)), buf)
End;
5: showflag(shownext, o);
6: OutTextXY(440, optiony+(optionyinc*(o-1)), xshapetitles[xshape]);
7: OutTextXY(440, optiony+(optionyinc*(o-1)), styleblocktitles[styleblocks]);
8: OutTextXY(440, optiony+(optionyinc*(o-1)), keybindingtitles[binding]);
9: begin
str(depth, buf);
outtextxy(440, optiony+(optionyinc*(o-1)), buf);
end;
10: showflag(showguide, o);
End
End; {-showoptions-}
Procedure rotateopt(o : byte);
Begin
SetTextJustify(RightText, TopText);
SetTextStyle(SmallFont, HorizDir, 4);
SetColor(Black);
showoption(o);
Case o Of
1: tournament := Not tournament;
2: tournamentgame := (tournamentgame+1) Mod ngames;
3: level := (level Mod maxlevel)+1;
4: height := (height+1) Mod ((2*maxheight)+1);
5: shownext := Not shownext;
6: xshape := (xshape Mod xshapelevels)+1;
7: styleblocks := (styleblocks Mod nstyletabs)+1;
8: begin
binding := (binding mod nkeybindings)+1;
if binding = nkeybindings then
keybindingtab[nkeybindings, 1] := 0
end;
9: begin
inc(depth);
if depth > maxdepth then depth := mindepth;
end;
10: showguide := not showguide;
End;
SetColor(colorhigh);
showoption(o)
End; {-rotateopt-}
Begin {-getoptions-}
drawoptions;
level := initlevel;
SetTextJustify(RightText, TopText);
SetTextStyle(SmallFont, HorizDir, 4);
SetColor(colorhigh);
For o := 1 To noptions Do
showoption(o);
SetVisualPage(page);
done := False;
o := 1;
Repeat
SetTextJustify(LeftText, TopText);
SetTextStyle(DefaultFont, HorizDir, 1);
SetColor(colorhigh);
OutTextXY(200, optiony+(optionyinc*(o-1))+3, optiontitles[o]);
OutTextXY(190, optiony+(optionyinc*(o-1))+3, #254);
Repeat Until KeyPressed;
ch := getkey;
Case hi(ch) of
1: Begin { escape }
done := True;
endrun := True
End;
57: done := True; { space }
35, 36, 72, 75: begin { H J up left }
SetColor(colornormal);
OutTextXY(200, optiony+(optionyinc*(o-1))+3, optiontitles[o]);
SetColor(0);
OutTextXY(190, optiony+(optionyinc*(o-1))+3, #254);
If o < 2 Then
o := noptions
Else
Dec(o)
End;
23, 28, 37: rotateopt(o); { I enter K }
38, 77, 80: begin { L right down }
SetColor(colornormal);
OutTextXY(200, optiony+(optionyinc*(o-1))+3, optiontitles[o]);
SetColor(0);
OutTextXY(190, optiony+(optionyinc*(o-1))+3, #254);
If o > noptions-1 Then
o := 1
Else
Inc(o)
End
End
Until done;
page := 1-page;
SetActivePage(page);
ClearDevice;
End; {-getoptions-}
Procedure fillfield(h : byte);
Var
i, j : integer;
k : byte;
Begin {-fillfield-}
For i := depth DownTo depth-(h-1) Do
Begin
k := Random(filladd)+fillbase;
For j := 1 To k Do
field[i, Random(blockcols)+1] := True
End
End; {-fillfield-}
Begin {-initgame-}
getoptions;
FillChar(field, SizeOf(field)-blockcols, 0);
FillChar(field[depth+1, 1], blockcols, 1);
{ FillChar(fieldshadows, SizeOf(fieldshadows), 0); }
If tournament Then
RandSeed := tournamentgame;
If height <> 0 Then
Begin
If height > maxheight Then
begin
if depth-(height-maxheight) < mindepth then
height := (depth-mindepth)+maxheight;
fillfield(height-maxheight);
bonus := (height-maxheight)+bonushidden
end
Else
Begin
if depth-height < mindepth then
height := depth-mindepth;
fillfield(height);
bonus := height
End
End
Else
bonus := 0;
If Not shownext Then
Inc(bonus, bonusnext);
if not showguide then
inc(bonus, bonusguide);
If Not showshadow Then
Inc(bonus, bonusshadow);
inc(bonus, (maxdepth-depth)*2);
rowsclear := 0;
score := 0;
Case xshape Of
1: shapemap := xshapeclassic;
2: shapemap := xshapeeasy;
3: shapemap := xshapemedium;
4: shapemap := xshapehard
End;
Move(xstyletabs[styleblocks], styletab, SizeOf(styletab));
if not endrun then
if binding = nkeybindings then
begin
if keybindingtab[nkeybindings, 1] = 0 then
getkeybindings
end
else
fillchar(keybindingtab[nkeybindings], sizeof(keybinding), 0);
move(keybindingtab[binding], keybinding, sizeof(keybinding))
End; {-initgame-}
procedure drawguide(c:byte);
var i:integer;
begin
setcolor(c);
setlinestyle(userbitln,$aaaa,normwidth);
for i := 1 to blockcols-1 do
line(colmin+(pixelsperblock*i)+1, rowmin,
colmin+(pixelsperblock*i)+1, rowmin+(pixelsperblock*depth));
setlinestyle(solidln,0,normwidth)
end;
Procedure drawscreen;
Procedure drawfieldwin;
Var
rowmaxpel : integer;
colminpel : integer;
colmaxpel : integer;
i : integer;
Begin {-drawfieldwin-}
rowmaxpel := getmaxy;
colminpel := colmin-pixelsperblock;
colmaxpel := colmax+pixelsperblock;
SetColor(colornormal);
SetFillPattern(filltab[1], colornormal);
Bar(colminpel, rowmin, colmin, rowmaxpel);
Bar(colmin, rowmax, colmax, rowmaxpel);
Bar(colmax, rowmin, colmaxpel, rowmaxpel);
Line(colminpel, rowmin, colminpel, rowmaxpel);
Line(colmin, rowmin, colmin, rowmax);
Line(colmax, rowmin, colmax, rowmax);
Line(colmaxpel, rowmin, colmaxpel, rowmaxpel);
Line(colminpel, rowmin, colmin, rowmin);
Line(colmin, rowmax, colmax, rowmax);
Line(colmax, rowmin, colmaxpel, rowmin);
Line(colminpel, rowmaxpel, colmaxpel, rowmaxpel);
if depth <> maxdepth then
begin
setfillpattern(filltab[1], colornormal);
bar(colmin+2, rowmin+(pixelsperblock*depth)+1, colmax-2,
rowmin+(pixelsperblock*maxdepth)-1);
end;
if showguide then
drawguide(colornormal)
End; {-drawfieldwin-}
Procedure drawnextwin;
Begin
SetColor(colornormal);
SetFillStyle(SolidFill, colornormal);
placewindow(35, 16, 201, 126);
SetTextStyle(DefaultFont, HorizDir, 1);
settextjustify(centertext, toptext);
OutTextXY(118, 114, 'Next')
End;
Procedure drawscorewin;
Begin
SetColor(colornormal);
SetFillStyle(SolidFill, colornormal);
placewindow(439, 16, 605, 126);
SetColor(colorhigh);
SetTextStyle(SansSerifFont, HorizDir, 4);
SetTextJustify(CenterText, TopText);
OutTextXY(522, 21, id);
SetColor(colornormal);
SetTextStyle(SmallFont, HorizDir, 4);
OutTextXY(522, 60, copyright);
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(LeftText, TopText);
OutTextXY(466, 75, 'Score:');
OutTextXY(466, 87, 'Value:');
OutTextXY(466, 99, 'Level:');
OutTextXY(466, 111, ' Rows:');
End; {-drawscorewin-}
Procedure drawhelpwin;
Begin
SetColor(colornormal);
SetFillStyle(SolidFill, colornormal);
placewindow(35, 224, 201, 334);
placewindow(439, 224, 605, 334);
SetColor(colorhigh);
SetTextStyle(DefaultFont, HorizDir, 1);
OutTextXY(58, 246, keynames[binding, keyleft]);
OutTextXY(58, 258, keynames[binding, keyrotateleft]);
OutTextXY(58, 270, keynames[binding, keyrotateright]);
OutTextXY(58, 282, keynames[binding, keyright]);
OutTextXY(58, 294, keynames[binding, keydrop]);
OutTextXY(58, 306, 'Esc');
OutTextXY(462, 246, '^B');
OutTextXY(462, 258, '^L');
OutTextXY(462, 270, '^N');
OutTextXY(462, 282, '^S');
OutTextXY(462, 294, '^X');
OutTextXY(462, 306, '^\');
SetColor(colornormal);
SetTextStyle(SmallFont, HorizDir, 4);
OutTextXY(90, 243, 'move left');
OutTextXY(90, 255, 'rotate left');
OutTextXY(90, 267, 'rotate right');
OutTextXY(90, 279, 'move right');
OutTextXY(90, 291, 'drop');
OutTextXY(90, 303, 'pause/quit');
OutTextXY(494, 243, 'block style');
OutTextXY(494, 255, 'change level');
OutTextXY(494, 267, 'show next');
OutTextXY(494, 279, 'toggle sound');
OutTextXY(494, 291, 'extended shapes');
OutTextXY(494, 303, 'quick exit')
End; {-drawhelpwin-}
Procedure refill;
Var
i, j : integer;
Begin {-refill-}
For i := depth DownTo depth-(height-1) Do
For j := 1 To blockcols Do
If field[i, j] Then
PutImage(colmin+(pixelsperblock*(j-1))+1,
rowmin+(pixelsperblock*(i-1)), filler^, XORPut)
End; {-refill-}
Begin {-drawscreen-}
ClearDevice;
drawfieldwin;
GetImage(colmin+1, rowmin, colmax-1, rowmin+pixelsperblock+1, emptyrow^);
drawnextwin;
drawscorewin;
drawhelpwin;
If height In [1..maxheight] Then
refill;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
ClearDevice;
drawfieldwin;
drawnextwin;
drawscorewin;
drawhelpwin;
If height In [1..maxheight] Then
refill;
End; {-drawscreen-}
procedure cleanup;
forward;
Procedure play;
Var
dropped : boolean;
endgame : boolean;
shape : byte;
orient : byte;
row, col : byte;
color : byte;
style : byte;
ch : word;
k : byte;
t, tdelay : longint;
nextshape : byte;
nextcolor : byte;
nextstyle : byte;
xsize : byte;
xvalue : integer;
oldscore : longint;
oldxvalue : integer;
oldlevel : byte;
oldxshape : byte;
oldrowsclear : word;
i, j : integer;
r, c : byte;
{ procedure fake;
var
a, b, c, d : pointer;
i, j : integer;
z : bufstr;
begin
i := imagesize(0, 0, getmaxx, getmaxy div 2);
j := imagesize(0, (getmaxy div 2)+1, getmaxx, getmaxy);
getmem(a, i); getmem(c, i);
getmem(b, j); getmem(d, j);
getimage(0, 0, getmaxx, getmaxy div 2, a^);
getimage(0, (getmaxy div 2)+1, getmaxx, getmaxy, b^);
setactivepage(1-page);
getimage(0, 0, getmaxx, getmaxy div 2, c^);
getimage(0, (getmaxy div 2)+1, getmaxx, getmaxy, d^);
textmode(c80);
repeat
write('C:>');
readln(z)
until z = 'exit';
dographics;
SetTextStyle(SmallFont, HorizDir, 4);
setvisualpage(page);
setactivepage(1-page);
putimage(0, 0, c^, normalput);
putimage(0, (getmaxy div 2)+1, d^, normalput);
setvisualpage(1-page);
setactivepage(page);
putimage(0, 0, a^, normalput);
putimage(0, (getmaxy div 2)+1, b^, normalput);
freemem(a, i); freemem(b, j); freemem(c, i); freemem(d, j)
end; }
Procedure scrolldown(rclr : byte;
var r : rinfotype);
Var
rz : Array [1..clearlimit] Of integer;
i, j : integer;
Begin {-scrolldown-}
For i := 1 To rclr Do
rz[i] := pixelsperblock*(r[i]-1);
For i := 1 To rclr Do
Begin
GetImage(colmin+1, rowmin, colmax-1, rz[i], scrollptr^);
PutImage(colmin+1, rowmin, emptyrow^, NormalPut);
PutImage(colmin+1, rowmin+pixelsperblock, scrollptr^, NormalPut);
if tones then
begin
Sound(cleartone);
Delay(cleartonedelay);
NoSound
end;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
PutImage(colmin+1, rowmin, emptyrow^, NormalPut);
PutImage(colmin+1, rowmin+pixelsperblock, scrollptr^, NormalPut)
End
End; {-scrolldown-}
Procedure drawshape;
Var
i : integer;
x, y, x1, y1 : integer;
p : pointer;
Begin {-drawshape-}
{ If showshadow Then
FillChar(fieldshadows, SizeOf(fieldshadows), 0); }
x := colmin+(pixelsperblock*(col-1))+1;
y := rowmin+(pixelsperblock*(row-1));
p := styletab[color, style];
PutImage(x, y, p^, XORPut);
{ If showshadow Then
Begin
PutImage(x, rowmax+1, shadows^, XORPut);
fieldshadows[col] := True
End; }
For i := 1 To xsize Do
Begin
x1 := x+xshapetab[shape, orient, i, 2];
y1 := y+xshapetab[shape, orient, i, 1];
If (y1 >= rowmin) Then
PutImage(x1, y1, p^, XORPut);
{ If showshadow And Not fieldshadows[col+yshapetab[shape, orient, i, 2]]
Then
Begin
PutImage(x1, rowmax+1, shadows^, XORPut);
fieldshadows[col+yshapetab[shape, orient, i, 2]] := True
End }
End
End; {-drawshape-}
Procedure dispscore;
Begin
If oldscore <> score Then
Begin
SetColor(Black);
Str(oldscore, buf);
OutTextXY(522, 72, buf);
SetColor(colorhigh);
Str(score, buf);
OutTextXY(522, 72, buf)
End;
If oldxvalue <> xvalue Then
Begin
SetColor(Black);
Str(oldxvalue, buf);
OutTextXY(522, 84, buf);
SetColor(colorhigh);
Str(xvalue, buf);
OutTextXY(522, 84, buf)
End;
If (oldlevel <> level) Or (oldxshape <> xshape) Then
Begin
SetColor(Black);
Str(oldlevel, buf);
buf := buf+' '+xshapetitles[oldxshape];
OutTextXY(522, 96, buf);
SetColor(colorhigh);
Str(level, buf);
buf := buf+' '+xshapetitles[xshape];
OutTextXY(522, 96, buf)
End;
If oldrowsclear <> rowsclear Then
Begin
SetColor(Black);
Str(oldrowsclear, buf);
OutTextXY(522, 108, buf);
SetColor(colorhigh);
Str(rowsclear, buf);
OutTextXY(522, 108, buf)
End
End; {-dispscore-}
Function chk : boolean;
Var
f : boolean;
x, y, r : shortint;
i : integer;
Begin {-chk-}
r := row+1;
f := field[r, col];
For i := 1 To xsize Do
Begin
y := r+yshapetab[shape, orient, i, 1];
x := col+yshapetab[shape, orient, i, 2];
If ((y >= 1) And (y <= depth+1)) And ((x >= 1) And (x <= blockcols))
Then
f := f Or field[y, x]
End;
chk := f
End; {-chk-}
Procedure chkmv(c : shortint);
Var
f1, f2 : boolean;
x, y : shortint;
i : integer;
xcol : shortint;
Begin {-chkmv-}
Inc(c, col);
f1 := (c >= 1) And (c <= blockcols);
If f1 Then
f2 := field[row, c]
Else
f2 := True;
For i := 1 To xsize Do
Begin
x := c+yshapetab[shape, orient, i, 2];
y := row+yshapetab[shape, orient, i, 1];
f1 := f1 And ((x >= 1) And (x <= blockcols));
If f1 And ((y >= 1) And (y <= depth)) Then
f2 := f2 Or field[y, x]
End;
If f1 And (Not f2) Then
Begin
xcol := col;
col := c;
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
col := xcol;
drawshape;
col := c
End
End; {-chkmv-}
Procedure chkrot(o : byte);
Var
f1, f2 : boolean;
xorient : byte;
x, y : shortint;
i : integer;
f : Text;
Begin {-chkrot-}
f1 := True;
f2 := False;
For i := 1 To xsize Do
Begin
y := row+yshapetab[shape, o, i, 1];
x := col+yshapetab[shape, o, i, 2];
f1 := f1 And ((x >= 1) And (x <= blockcols)) And
(y <= depth);
If f1 And (y >= 1) Then
f2 := f2 Or field[y, x]
End;
If f1 And (Not f2) Then
Begin
xorient := orient;
orient := o;
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
orient := xorient;
drawshape;
orient := o
End
End; {-chkrot-}
Procedure dropshape;
Var
oldrow, xrow : byte;
Begin {-dropshape-}
oldrow := row;
While Not chk Do
Inc(row);
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
xrow := row;
row := oldrow;
drawshape;
row := xrow;
inc(score, level*oldrow+bonus);
{ Inc(score, level*(row-oldrow)+bonus); }
dropped := True
End; {-dropshape-}
Procedure chkrows;
Var
f : boolean; i : integer;
rows : byte;
r : byte;
rinfo : rinfotype;
Function chkrow(r : byte) : boolean;
Var
f : boolean;
i, j : integer;
Begin {-chkrow-}
f := False;
If r < depth+1 Then
Begin
f := field[r, 1];
i := 2;
While f And (i <= blockcols) Do
Begin
f := f And field[r, i];
Inc(i)
End;
If f Then
Begin
Inc(rowsclear);
If (level < maxlevel) And (rowsclear = advancetab[level]) Then
Begin
Inc(level);
tdelay := timedelaytab[level]
End;
Move(field[0, 1], field[1, 1], blockcols*r);
Inc(score, level*bonusrowclear+bonus)
End
End;
chkrow := f
End; {-chkrow-}
Begin {-chkrows-}
rows := 0;
For r := row-2 To row+2 Do
If chkrow(r) Then
Begin
Inc(rows);
rinfo[rows] := r
End;
If rows > 0 Then
Begin
scrolldown(rows, rinfo);
If rows > 1 Then
Inc(score, level*((rows-1)*bonusmultclear)+bonus);
f := false;
I := 1;
while (not f) and (i <= blockcols) do
begin
f := f or field[depth, i];
inc(i);
end;
if not f then
inc(score, level*bonusempty+bonus);
End
End; {-chkrows-}
Procedure gameover;
Var
i, x, y, p : integer;
f : boolean;
Begin {-gameover-}
f := True;
For y := 1 To depth Do
For p := 1 To 2 Do
Begin
For x := 1 To blockcols Do
Begin
If Not field[y, x] Then
PutImage(colmin+(pixelsperblock*(x-1))+1,
rowmin+(pixelsperblock*(y-1)),
curtain[f]^, NormalPut);
f := Not f
End;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
If Not KeyPressed Then
Delay(dropdelay)
End;
setcolor(0);
setfillstyle(solidfill, 0);
bar(colmin+1, rowmin, colmax-1, rowmin+pixelsperblock);
SetColor(colorhigh);
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(CenterText, TopText);
OutTextXY(320, rowmin+4, 'Game Over');
i := 1;
Repeat
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
Delay(i*dropdelay);
Inc(i)
Until (i > 25) Or (Not Odd(i) And KeyPressed);
While KeyPressed Do
ch := getkey
End; {-gameover-}
Begin {-play-}
initlevel := level;
endgame := False;
nextshape := Random(shapemap)+1;
nextcolor := Random(ncolors)+1;
nextstyle := Random(nstyles)+1;
xvalue := 0;
tdelay := timedelaytab[level];
oldscore := 255;
oldlevel := 255;
oldxvalue := 0;
oldxshape := (xshape+1) Mod xshapelevels;
oldrowsclear := 65535;
{ dispscore;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
dispscore;
oldscore := 0;
oldlevel := level;
oldxvalue := xvalue;
oldxshape := xshape;
oldrowsclear := 0; }
If shownext Then
putshape(111, 54, nextshape, styletab[nextcolor, nextstyle]);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
If shownext Then
putshape(111, 54, nextshape, styletab[nextcolor, nextstyle]);
Repeat
Inc(score, xvalue);
shape := nextshape;
orient := 0;
row := initrow;
col := initcol;
color := nextcolor;
style := nextstyle;
dropped := False;
xsize := shapetab[shape, info, 1];
xvalue := level*shapetab[shape, info, 2]+bonus;
nextshape := Random(shapemap)+1;
nextcolor := Random(ncolors)+1;
nextstyle := Random(nstyles)+1;
drawshape;
dispscore;
If shownext Then
Begin
putshape(111, 54, shape, styletab[color, style]);
putshape(111, 54, nextshape, styletab[nextcolor, nextstyle])
End;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
dispscore;
If shownext Then
Begin
putshape(111, 54, shape, styletab[color, style]);
putshape(111, 54, nextshape, styletab[nextcolor, nextstyle])
End;
oldscore := score;
oldxvalue := xvalue;
oldlevel := level;
oldxshape := xshape;
oldrowsclear := rowsclear;
t := gettimer+tdelay;
Repeat Until (gettimer > t);
While KeyPressed Do
ch := getkey;
If chk Then
endgame := True
Else
Begin
Repeat
Inc(row);
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
Dec(row);
drawshape;
Inc(row);
t := gettimer+tdelay;
Repeat
Repeat Until KeyPressed Or (gettimer > t);
If KeyPressed Then
Begin
ch := getkey;
if lo(ch) < 29 then
case hi(ch) of
{ Esc } 1: begin
{ 1, 68: Begin
if hi(ch) = 68 then
fake; }
Repeat Until KeyPressed;
ch := getkey;
If chr(lo(ch)) = #27 Then
Begin
dropshape;
endgame := True
End
End;
{ ^W } { 17: Begin
showshadow := Not showshadow;
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
showshadow := Not showshadow;
drawshape;
showshadow := Not showshadow;
If showshadow Then
Dec(bonus, bonusshadow)
Else
Inc(bonus, bonusshadow);
While KeyPressed Do
ch := getkey
End; }
{ ^S } 31: tones := not tones;
{ ^L } 38, 47: Begin
level := (level Mod maxlevel)+1;
tdelay := timedelaytab[level];
drawshape;
dispscore;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
drawshape;
dispscore;
oldlevel := level;
While KeyPressed Do
ch := getKey
End;
{ ^\ } 43: begin
cleanup;
halt
end;
{ ^X } 45: Begin
xshape := (xshape Mod xshapelevels)+1;
Case xshape Of
1: shapemap := xshapeclassic;
2: shapemap := xshapeeasy;
3: shapemap := xshapemedium;
4: shapemap := xshapehard
End;
drawshape;
dispscore;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
drawshape;
dispscore;
oldxshape := xshape;
While KeyPressed Do
ch := getkey
End;
{ ^B } 48: Begin
i := styleblocks;
If shownext Then
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
styleblocks := (styleblocks Mod nstyletabs)+1;
Move(xstyletabs[styleblocks], styletab,
SizeOf(styletab));
drawshape;
If shownext Then
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
Move(xstyletabs[i], styletab,
SizeOf(styletab));
drawshape;
If shownext Then
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
Move(xstyletabs[styleblocks], styletab,
SizeOf(styletab));
If shownext Then
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
While KeyPressed Do
ch := getkey
End;
{ ^G } { 34: begin
showguide := not showguide;
if showguide then
begin
dec(bonus, bonusguide);
drawshape;
drawguide(colornormal);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
drawshape;
drawguide(colornormal);
end
else begin
inc(bonus, bonusguide);
drawshape;
drawguide(0);
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
drawshape;
drawguide(0);
end;
end; }
{ ^N } 49: Begin
shownext := Not shownext;
If shownext Then
Dec(bonus, bonusnext)
Else
Inc(bonus, bonusnext);
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
drawshape;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
putshape(111, 54, nextshape,
styletab[nextcolor, nextstyle]);
drawshape;
While KeyPressed Do
ch := getkey
End
end
else
begin
k := 1;
while (hi(ch) <> keybinding[k]) and (k <= nkeys) do
inc(k);
if k <= nkeys then
case k of
keydrop: dropshape;
keyleft: chkmv(left);
keyright: chkmv(right);
keyrotateright: chkrot((orient+1) Mod (norients+1));
keyrotateleft: chkrot((norients+orient) Mod (norients+1))
end
end;
end;
Until dropped Or (gettimer > t);
Until dropped Or chk;
drawshape;
field[row, col] := True;
For i := 1 To xsize Do
field[row+yshapetab[shape, orient, i, 1],
col+yshapetab[shape, orient, i, 2]] := True;
chkrows;
t := gettimer+(tdelay Shr 1);
Repeat Until (gettimer > t);
While KeyPressed Do
ch := getkey
End;
Until endgame;
dispscore;
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
dispscore;
oldscore := score;
oldxvalue := xvalue;
oldlevel := level;
oldxshape := xshape;
oldrowsclear := rowsclear;
While KeyPressed Do
ch := getkey;
gameover;
Repeat Until KeyPressed;
While KeyPressed Do
ch := getkey
End;
Procedure postgame;
Var
ch : word;
today : DateTime;
i, j : word;
rank, x, s : integer;
Begin
rank := 0;
If rowsclear > 0 Then
Begin
i := 1;
While (i <= nhiscores) And (hiscore[i].score >= score) Do
Inc(i);
If i <= nhiscores Then
Begin
rank := i;
For j := nhiscores-1 DownTo i Do
hiscore[j+1] := hiscore[j];
hiscore[i].score := score;
hiscore[i].level := level;
hiscore[i].rowsclear := rowsclear;
GetTime(today.hour, today.min, today.sec, j);
GetDate(today.year, today.month, today.day, j);
Dec(today.year, 1900);
Str(today.month:2, hiscore[i].date);
Str(today.day:2, buf);
hiscore[i].date := hiscore[i].date+'/'+buf;
Str(today.year:2, buf);
hiscore[i].date := hiscore[i].date+'/'+buf;
fillzero(hiscore[i].date);
Str(today.hour:2, hiscore[i].time);
Str(today.min:2, buf);
hiscore[i].time := hiscore[i].time+':'+buf;
Str(today.sec:2, buf);
hiscore[i].time := hiscore[i].time+':'+buf;
fillzero(hiscore[i].time);
hiscore[i].version := version;
ClearDevice;
SetTextJustify(CenterText, TopText);
SetTextStyle(SansSerifFont, HorizDir, 4);
SetColor(colorhigh);
OutTextXY(320, 5, 'Congratulations!');
SetTextStyle(DefaultFont, HorizDir, 1);
SetColor(colornormal);
OutTextXY(320, 46, 'You''ve made it into the Glorious Fifteen;');
OutTextXY(320, 58, 'please enter your name for posterity:');
SetColor(colornormal);
placewindow(214, 155, 426, 195);
SetVisualPage(page);
page := 1-page;
SetTextStyle(SmallFont, HorizDir, 4);
x := 1;
Repeat
SetColor(colorhigh);
OutTextXY(224+6*(x-1), 171, '_');
Repeat Until KeyPressed;
ch := getkey;
Case lo(ch) Of
0: While KeyPressed Do
ch := getkey;
8: If x > 1 Then
Begin
SetColor(Black);
OutTextXY(224+6*(x-1), 171, '_');
Dec(x);
OutTextXY(224+6*(x-1), 171, hiscore[i].name[x])
End;
13: hiscore[i].name[0] := Chr(x-1);
27: If x > 1 Then
Begin
SetColor(Black);
OutTextXY(224+6*(x-1), 171, '_');
For s := x DownTo 1 Do
OutTextXY(224+6*(s-1), 171, hiscore[i].name[s]);
x := 1
End;
Else If x < SizeOf(bufstr) Then
Begin
SetColor(Black);
OutTextXY(224+6*(x-1), 171, '_');
SetColor(colorhigh);
OutTextXY(224+6*(x-1), 171, chr(lo(ch)));
hiscore[i].name[x] := chr(lo(ch));
Inc(x)
End
End
Until (lo(ch) = 13) or (x > SizeOf(bufstr))
End
End;
SetActivePage(page);
ClearDevice;
SetTextStyle(SansSerifFont, HorizDir, 4);
SetTextJustify(CenterText, TopText);
SetColor(colorhigh);
OutTextXY(320, 5, 'The Glorious Fifteen');
SetColor(colornormal);
SetFillStyle(SolidFill, colornormal);
placewindow(16, 50, 615, 256);
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(LeftText, TopText);
SetColor(colorhigh);
OutTextXY(24, 60, 'Rank Score Level Rows Date Time Name');
SetColor(colornormal);
SetTextStyle(SmallFont, HorizDir, 4);
For i := 1 To nhiscores Do
Begin
If rank = i Then
SetColor(colorhigh);
SetTextJustify(CenterText, TopText);
Str(i:2, buf);
OutTextXY(40, 72+12*(i-1), buf);
If hiscore[i].score <> 0 Then
Begin
Str(hiscore[i].score:7, buf);
OutTextXY(92, 72+12*(i-1), buf);
Str(hiscore[i].level:2, buf);
OutTextXY(148, 72+12*(i-1), buf);
Str(hiscore[i].rowsclear:4, buf);
OutTextXY(192, 72+12*(i-1), buf);
OutTextXY(248, 72+12*(i-1), hiscore[i].date);
OutTextXY(320, 72+12*(i-1), hiscore[i].time);
SetTextJustify(LeftText, TopText);
OutTextXY(360, 72+12*(i-1), hiscore[i].name);
OutTextXY(563, 72+12*(i-1), hiscore[i].version)
End;
If rank = i Then
SetColor(colornormal)
End;
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(CenterText, TopText);
SetColor(colornormal);
OutTextXY(320, 300, 'Press Y to try again or N to exit.');
SetVisualPage(page);
page := 1-page;
SetActivePage(page);
ClearDevice;
Repeat
Repeat Until KeyPressed;
ch := getkey;
Until (hi(ch) In [21, 49]);
endrun := hi(ch) = 49
End;
{ 12345678901234567890123456789012345678901234567890123456789012345678901234
rank score level rows date time name'
00 0000000 00 0000 00/00/00 00:00:00 12345678901234567890123456789012
}
Procedure cleanup;
Var
i : integer;
Procedure configflag(f : boolean);
Begin
If f Then
WriteLn(fconfig, 'Yes')
Else
WriteLn(fconfig, 'No')
End; {-configflag-}
Begin {-cleanup-}
dotext;
Assign(fhiscore, hiscorename);
filemode := 2;
Rewrite(fhiscore);
if ioresult = 0 then
begin
i := 1;
While (i <= nhiscores) And (hiscore[i].score > 0) Do
Begin
Write(fhiscore, hiscore[i]);
Inc(i)
End;
Close(fhiscore)
end;
Assign(fconfig, configname);
filemode := 2;
Rewrite(fconfig);
if ioresult = 0 then
begin
WriteLn(fconfig, '# ', id, '':1, version, ' configuration file');
{ WriteLn(fconfig, '# ', copyright); }
Write(fconfig, 'display=');
Case display Of
bw : writeln(fconfig, 'BW');
color : WriteLn(fconfig, 'Color');
mono : WriteLn(fconfig, 'Mono');
plasma: WriteLn(fconfig, 'Plasma')
End;
writeln(fconfig, 'depth=', depth);
WriteLn(fconfig, 'height=', height);
WriteLn(fconfig, 'level=', initlevel);
Write(fconfig, 'shownext=');
configflag(shownext);
write(fconfig, 'showguide=');
configflag(showguide);
{ Write(fconfig, 'showshadow=');
configflag(showshadow); }
Write(fconfig, 'sound=');
configflag(tones);
WriteLn(fconfig, 'styleblocks=', styleblocktitles[styleblocks]);
Write(fconfig, 'title=');
configflag(title);
Write(fconfig, 'tournament=');
configflag(tournament);
WriteLn(fconfig, 'tournamentgame=', tournamentgame);
WriteLn(fconfig, 'xshape=', xshapetitles[xshape]);
write(fconfig, 'palette=');
for i := 0 to palettesiz-2 do
write(fconfig, userpalette.colors[i], ',');
writeln(fconfig, userpalette.colors[palettesiz-1]);
write(fconfig, 'keybinding=');
if binding <> nkeybindings then
writeln(fconfig, keybindingtitles[binding])
else
begin
for i := 1 to nkeys-1 do
write(fconfig, keybinding[i], ',');
writeln(fconfig, keybinding[nkeys]);
end;
Close(fconfig)
end;
numlock(false)
End; {-cleanup-}
Begin
init;
drawtitle;
Repeat
initgame;
If Not endrun Then
Begin
drawscreen;
play;
postgame
End;
Until endrun;
cleanup
End.